package csv;

import Constant.Constant;
import common.Charset;
import common.NslHeadLineInfo;
import string.UtilString;
import string.UtilStringChartset;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Description: csv util, the class has a bug which will appeared when the string has ",".
 * Created by E440 on 2017/4/30.
 *
 *
 */
public class UtilCsv {
    /**
     * 将dataList 导出到File文件,行分割符为 \r \n
     *
     * @param file csv文件(路径+文件名)，csv文件不存在会自动创建
     * @param dataList 数据
     * @return
     */
   /* public static boolean writeCsvFile(File file, List<String> dataList){
        boolean isSucess=false;

        FileOutputStream out=null;
        OutputStreamWriter osw=null;
        BufferedWriter bw=null;
        try {
            out = new FileOutputStream(file);
            osw = new OutputStreamWriter(out);
            bw =new BufferedWriter(osw);
            if(dataList!=null && !dataList.isEmpty()){
                for(String data : dataList){
                    bw.append(data).append("\r").append("\n");
                }
            }
            isSucess=true;
        } catch (Exception e) {
            isSucess=false;
        }finally{
            if(bw!=null){
                try {
                    bw.close();
                    bw=null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(osw!=null){
                try {
                    osw.close();
                    osw=null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out!=null){
                try {
                    out.close();
                    out=null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return isSucess;
    }*/

    /**
     * 读取csv文件到List<String>数组，其中每一行为一个元素.
     *
     * @param file csv文件(路径+文件)
     * @return
     */
    public static List<String> readCsvFile(File file) throws IOException {
        List<String> dataList=new ArrayList<String>();
        try(BufferedReader br = new BufferedReader(new FileReader(file));) {

            String line = "";
            while ((line = br.readLine()) != null) {
                dataList.add(line);
            }
        }
        return dataList;
    }

    /**
     * @param csvFileAbs
     * @param beginRow
     * @param endRow
     * @return
     */
    public static List<String> getLines(String  csvFileAbs,Integer beginRow,Integer endRow) throws IOException {
        return getLines(csvFileAbs,beginRow,endRow,null);
    }

    /** 读取csv指定行
     * @param csvFileAbs
     * @param beginRow
     * @param endRow
     * @param charset
     * @return
     * @throws IOException
     */
    public static List<String> getLines(String  csvFileAbs,Integer beginRow,Integer endRow,String charset) throws IOException {
        if(charset==null){
            charset=Charset.GBK;
        }
        List<String> dataList=new ArrayList<String>();
        if(beginRow<0 || endRow <0 || beginRow>endRow){
            throw new RuntimeException("BeginRow or endRow is illegal. ");
        }
        int i=1;
        try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(csvFileAbs),charset))) {
            String line = "";
            while ((line = br.readLine()) != null) {
                if(i<beginRow){
                    continue;
                }
                if(i>endRow){
                    break;
                }
                dataList.add(line);
                i++;
            }
        }
        return dataList;
    }

    public static  List<String> getTopLines(String  csvFileAbs,Integer count,String charset) throws IOException {
        List<String> topLines=getLines(csvFileAbs,0,count,charset);
        return  topLines;
    }

    public static  List<String> getTopLines(String  csvFileAbs,Integer count) throws IOException {
        List<String> topLines=getLines(csvFileAbs,0,count);
        return  topLines;
    }

    /**
     * 将dataList 导出到File文件,行分割符为 \r \n
     *
     * @param file csv文件(路径+文件名)，csv文件不存在会自动创建
     * @param dataList 数据
     * @return
     */
    public static boolean writeCsvFile(File file, List<String> dataList,String charset)  {
        boolean isSucess=false;
        try(FileOutputStream out=new FileOutputStream(file);
            OutputStreamWriter osw=new OutputStreamWriter(out);
            BufferedWriter bw =new BufferedWriter(osw)){
            if(dataList!=null && !dataList.isEmpty()){
                for(String data : dataList){
                    data= UtilStringChartset.changeCharset(data,charset);
                    bw.append(data).append("\r").append("\n");
                }
            }
            isSucess=true;
        }catch (Exception e){
            isSucess=false;
        }
        return isSucess;
    }


    public static boolean writeCsvFile(File file, List<String> dataList){
       return writeCsvFile(file,dataList, Charset.UTF_8);
    }


    /**读取表头信息，表头判定，根据 前20行 元素不为空的 数量最大的列，判定为表头
     * @param csvFileAbs
     * @param charset csv文件的编码
     * @return
     * @throws IOException
     */
    public static NslHeadLineInfo getHeadLineInfo(String csvFileAbs,String charset) throws IOException {

        List<String> lineList=getTopLines(csvFileAbs,20,charset);
        //找出每行不为空的元素个数
        //Map<Integer,Integer> countMap=new HashMap<>();
        int maxLine=0;//记录不为空的 最大元素的行编号
        int maxCount=0;
        for (int i = 0; i < lineList.size(); i++) {
            String line=lineList.get(i);
            String[] values=line.split(Constant.CSV_SPLIT_BY);
            int count=0;
            for (String value : values) {
                if(!UtilString.isNullOrEmpty(value)){
                    count++;
                }
            }

            if(count>maxCount){
                maxCount=count;
                maxLine=i;
            }
        }
        if (maxCount==0){
            return null;
        }
        String headLine=lineList.get(maxLine);
        //System.out.println(headLine);
        String[] headValues=headLine.split(Constant.CSV_SPLIT_BY);
        NslHeadLineInfo headLineInfo=new NslHeadLineInfo();
        headLineInfo.setHeadLineIndex(maxLine);
        for (int i = 0; i < headValues.length; i++) {

            headLineInfo.getHeadLineMap().put(headValues[i],i);
        }
        return  headLineInfo;
    }


    /** 读取表头信息，表头判定，根据 前20行 元素不为空的且和传入set 匹配次数  数量最大的列，判定为表头
     * @param csvFileAbs
     * @param headNameSet  和表头对比的set
     * @param charset csv文件的编码
     * @return
     * @throws IOException
     */
    public static NslHeadLineInfo getHeadLineInfo(String csvFileAbs,Set<String> headNameSet,String charset) throws IOException {
        List<String> lineList=getTopLines(csvFileAbs,20,charset);
        //找出每行不为空的元素个数
        //Map<Integer,Integer> countMap=new HashMap<>();
        int maxLine=0;//记录不为空的 最大元素的行编号
        int maxCount=0;
        for (int i = 0; i < lineList.size(); i++) {
            String line=lineList.get(i);
            String[] values=line.split(Constant.CSV_SPLIT_BY);
            int count=0;
            for (String value : values) {
                if(!UtilString.isNullOrEmpty(value)){
                    if(headNameSet.contains(value)){
                        count++;
                        headNameSet.remove(value);
                    }
                }
            }
            if(count>=maxCount){
                maxCount=count;
                maxLine=i;
            }
        }
        if (maxCount==0){
            return null;
        }
        String headLine=lineList.get(maxLine);
        String[] headValues=headLine.split(Constant.CSV_SPLIT_BY);
        NslHeadLineInfo headLineInfo=new NslHeadLineInfo();
        headLineInfo.setHeadLineIndex(maxLine);
        for (int i = 0; i < headValues.length; i++) {
            headLineInfo.getHeadLineMap().put(headValues[i],i);
        }
        return  headLineInfo;
    }
}

